<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="UTF-8">
    <meta http-equiv="X-UA-Compatible" content="IE=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1.0">
    <title>Document</title>
</head>

<body>
    <!-- <script为什么放在最后？ -->
    <!-- script是同步加载，会阻塞dom解析 -->
    <!-- 放在最上面没有办法获得dom -->
    <!-- script之间如果存在依赖关系，需要按照顺序加载script -->
    <!-- script为什么不是异步的？ -->
    <!-- DOM树还没有加载，js开始运行，会报错。造成dom冲突 -->

    <!-- 异步加载使用的时机 -->
    <!-- 异步加载文件中不要直接操作dom -->
    <!-- 与页面结构无关的 -->
    <!-- 按需加载的文件 -->

    <!-- defer ie8版本 -->
    <!-- 异步加载 加载完并不立即执行，等dom树构建完成，在执行 -->
    <script src="./js/utils.js" defer></script>

    <!-- async w3c的标准，HTML5属性 ie9及以上支持 -->
    <!-- 加载完成立即执行 -->
    <script src="./js/utils.js" async></script>
    <!-- 第三种方法 -->
    <!-- 在widow.onload之后执行 -->
    <script>
        // (
        //     function() {
        //         function async_load() {
        //             var s = document.createElement('script');
        //             s.type = 'text/javascript';
        //             // 此时已经开始下载,资源下载
        //             s.src = './js/utils.js';
        //             // 元素放在dom中，utils开始执行
        //             document.body.appendChild(s);
        //         }
        // onload会在异步和资源全部加载完成之后执行，为了防止阻塞onload，选择在onload之后执行
        //         if (window.attachEvent) {
        //             window.attachEvent('onload', async_load);
        //         } else {
        //             window.addEventListener('load', async_load)
        //         }
        //     }
        // )()


        // 即异步加载，又立即执行文件中的某一个函数
        exec_util_width_loading_script('./js/utils.js', 'test')

        function exec_util_width_loading_script(url, fn) {
            var s = document.createElement("script");
            s.type = 'text/javascript';
            //  s.readyState文件的加载状态
            // 加载完成后，执行utils文件中方法
            if (s.readyState) {
                s.onreadystatechange = function() {
                    var state = s.readyState;
                    if (state === 'complate' || state === 'loaded') {
                        utils[fn]()
                    }
                }
            } else {
                s.onload = function() {
                    utils[fn]()
                }
            }
            s.src = url;
            document.body.appendChild(s);
        }
    </script>

    <!-- 创建的script是异步加载 -->
    <script>
        var s = document.createElement('script');
        s.type = 'text/javascript';
        s.src = './js/utils.js';
        document.body.appendChild(s);
    </script>
    <script>
        // 命名空间可以让函数知道出自哪里，更容易维护
        var utils = {
            test: function() {
                console.log('test');
            }
        }
        utils.test();
    </script>
</body>

</html>